﻿using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using System.Security.Cryptography.X509Certificates;

namespace AiQiuQuan.Sport.Core.WechatPayV3
{
    /// <summary>
    /// 证书工具
    /// </summary>
    public class CertificateTool
    {
        /// <summary>
        /// 安装证书
        /// </summary>
        /// <param name="filePath">证书路径</param>
        /// <param name="password">证书密码</param>
        private static X509Certificate2 InstallCertificate(string filePath, string password)
        {
            if (File.Exists(filePath))
            {
                try
                {
                    return new X509Certificate2(filePath, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
                }
                catch (Exception ex)
                {
                    LogTool.Error($"证书安装错误:{ex.Message}");
                    return null;
                }
            }

            LogTool.Error($"证书路径不存在:{filePath}");
            return null;
        }

        /// <summary>
        /// 导出证书(序列号,私钥(xml))
        /// </summary>
        /// <param name="filePath">证书路径</param>
        /// <param name="password">证书密码</param>
        public static (string, string?) GetSerialAndPrivateKey(string filePath, string password)
        {
            var certifcate = InstallCertificate(filePath, password);
            if (certifcate == null)
            {
                return (string.Empty, string.Empty);
            }

            return (certifcate.SerialNumber, certifcate.GetRSAPrivateKey()?.ToXmlString(true));
        }

        /// <summary>
        /// 导出证书(序列号,pem私钥)
        /// </summary>
        /// <param name="filePath">证书路径</param>
        /// <param name="password">证书密码</param>
        public static (string, string?) GetSerialAndPrivatePem(string filePath, string password)
        {
            var certifcate = InstallCertificate(filePath, password);
            if (certifcate == null)
            {
                return (string.Empty, string.Empty);
            }

            var privatePem = string.Empty;
            var rsa2 = certifcate.GetRSAPrivateKey();
            var p = rsa2.ExportParameters(true);
            var key = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
                new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
                new BigInteger(1, p.InverseQ));

            using (TextWriter sw = new StringWriter())
            {
                var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                pemWriter.WriteObject(key);
                pemWriter.Writer.Flush();
                privatePem = sw.ToString();
            }

            return (certifcate.GetSerialNumberString(), privatePem);
        }
    }
}
